From cadeca74e21a0990270b0527497bfcc0d6910158 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 19 Feb 2020 22:04:28 -0500 Subject: [PATCH] Go back to ::enter/::leave for pointer changes These signals are behaving a little differently from what ::focus-in/::focus-out used to do. --- docs/reference/gtk/gtk4-docs.xml | 1 + docs/reference/gtk/gtk4-sections.txt | 26 ++++++++-- docs/reference/gtk/gtk4.types.in | 1 + gtk/gtkeventcontrollerfocus.c | 43 +++++++++++++---- gtk/gtkeventcontrollermotion.c | 72 ++++++++++++++++++---------- gtk/gtkiconview.c | 35 +++++--------- gtk/gtklabel.c | 29 ++++------- gtk/gtkmodelbutton.c | 32 +++++++------ gtk/gtkpopovermenu.c | 19 +++----- gtk/gtkpopovermenubar.c | 36 ++++++-------- gtk/gtkscrolledwindow.c | 22 ++++----- gtk/gtktreepopover.c | 19 +++----- gtk/gtktreeview.c | 71 ++++++++++++++------------- testsuite/gtk/focus.c | 53 +++++++++----------- 14 files changed, 240 insertions(+), 219 deletions(-) diff --git a/docs/reference/gtk/gtk4-docs.xml b/docs/reference/gtk/gtk4-docs.xml index 6539b80af6..1f6eddd057 100644 --- a/docs/reference/gtk/gtk4-docs.xml +++ b/docs/reference/gtk/gtk4-docs.xml @@ -321,6 +321,7 @@ Gestures and event handling + diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index 6b4dfca4b1..9961438757 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -6170,10 +6170,6 @@ gtk_event_controller_key_set_im_context gtk_event_controller_key_get_im_context gtk_event_controller_key_forward gtk_event_controller_key_get_group -gtk_event_controller_key_get_focus_origin -gtk_event_controller_key_get_focus_target -gtk_event_controller_key_contains_focus -gtk_event_controller_key_is_focus GTK_TYPE_EVENT_CONTROLLER_KEY @@ -6187,6 +6183,28 @@ GTK_EVENT_CONTROLLER_KEY_GET_CLASS gtk_event_controller_key_get_type +
+gtkeventcontrollerfocus +GtkEventControllerFocus +GtkEventControllerFocus +gtk_event_controller_focus_new +gtk_event_controller_focus_get_focus_origin +gtk_event_controller_focus_get_focus_target +gtk_event_controller_focus_contains_focus +gtk_event_controller_focus_is_focus + + +GTK_TYPE_EVENT_CONTROLLER_FOCUS +GTK_EVENT_CONTROLLER_FOCUS +GTK_EVENT_CONTROLLER_FOCUS_CLASS +GTK_IS_EVENT_CONTROLL_FOCUS +GTK_IS_EVENT_CONTROLLER_FOCUS_CLASS +GTK_EVENT_CONTROLLER_FOCUS_GET_CLASS + + +gtk_event_controller_focus_get_type +
+
gtkgesturedrag GtkGestureDrag diff --git a/docs/reference/gtk/gtk4.types.in b/docs/reference/gtk/gtk4.types.in index 40f027d09d..1c7b9eabb2 100644 --- a/docs/reference/gtk/gtk4.types.in +++ b/docs/reference/gtk/gtk4.types.in @@ -68,6 +68,7 @@ gtk_entry_completion_get_type gtk_entry_get_type gtk_event_controller_get_type gtk_event_controller_key_get_type +gtk_event_controller_focus_get_type gtk_event_controller_legacy_get_type gtk_event_controller_motion_get_type gtk_event_controller_scroll_get_type diff --git a/gtk/gtkeventcontrollerfocus.c b/gtk/gtkeventcontrollerfocus.c index 2c7f963a9e..0cec4344e9 100644 --- a/gtk/gtkeventcontrollerfocus.c +++ b/gtk/gtkeventcontrollerfocus.c @@ -24,7 +24,7 @@ * @See_also: #GtkEventController * * #GtkEventControllerFocus is an event controller meant for situations - * where you need to know where the focusboard focus is. + * where you need to know where the focus is. **/ #include "config.h" @@ -97,18 +97,28 @@ update_focus (GtkEventController *controller, if (crossing->direction == GTK_CROSSING_IN) { + if (crossing->new_descendent != NULL) + { + contains_focus = TRUE; + } if (crossing->new_target == widget) - is_focus = TRUE; - if (crossing->new_target != NULL) + { + contains_focus = TRUE; + is_focus = TRUE; + } + } + else + { + if (crossing->new_descendent != NULL || + crossing->new_target == widget) contains_focus = TRUE; + is_focus = FALSE; } if (focus->contains_focus != contains_focus) { - if (contains_focus) - enter = TRUE; - else - leave = TRUE; + enter = contains_focus; + leave = !contains_focus; } if (leave) @@ -227,6 +237,13 @@ gtk_event_controller_focus_class_init (GtkEventControllerFocusClass *klass) * * This signal is emitted whenever the focus enters into the * widget or one of its descendents. + * + * Note that this means you may not get an ::enter signal + * even though the widget becomes the focus location, in + * certain cases (such as when the focus moves from a descendent + * of the widget to the widget itself). If you are interested + * in these cases, you can monitor the #GtkEventControllerFocus:is-focus + * property for changes. */ signals[ENTER] = g_signal_new (I_("enter"), @@ -240,8 +257,16 @@ gtk_event_controller_focus_class_init (GtkEventControllerFocusClass *klass) * GtkEventControllerFocus::leave: * @controller: the object which received the signal * - * This signal is emitted whenever the focus leaves from - * the widget or one of its descendents. + * This signal is emitted whenever the focus leaves the + * widget hierarchy that is rooted at the widget that the + * controller is attached to. + * + * Note that this means you may not get a ::leave signal + * even though the focus moves away from the widget, in + * certain cases (such as when the focus moves from the widget + * to a descendent). If you are interested in these cases, you + * can monitor the #GtkEventControllerFocus:is-focus property + * for changes. */ signals[LEAVE] = g_signal_new (I_("leave"), diff --git a/gtk/gtkeventcontrollermotion.c b/gtk/gtkeventcontrollermotion.c index 4134ce1335..3adbad42b9 100644 --- a/gtk/gtkeventcontrollermotion.c +++ b/gtk/gtkeventcontrollermotion.c @@ -54,8 +54,9 @@ struct _GtkEventControllerMotionClass }; enum { + ENTER, + LEAVE, MOTION, - POINTER_CHANGE, N_SIGNALS }; @@ -91,12 +92,16 @@ gtk_event_controller_motion_handle_event (GtkEventController *controller, static void update_pointer_focus (GtkEventController *controller, - const GtkCrossingData *crossing) + const GtkCrossingData *crossing, + double x, + double y) { GtkEventControllerMotion *motion = GTK_EVENT_CONTROLLER_MOTION (controller); GtkWidget *widget = gtk_event_controller_get_widget (controller); gboolean is_pointer = FALSE; gboolean contains_pointer = FALSE; + gboolean enter = FALSE; + gboolean leave = FALSE; if (crossing->direction == GTK_CROSSING_IN) { @@ -106,6 +111,17 @@ update_pointer_focus (GtkEventController *controller, contains_pointer = TRUE; } + if (motion->contains_pointer != contains_pointer) + { + if (contains_pointer) + enter = TRUE; + else + leave = TRUE; + } + + if (leave) + g_signal_emit (controller, signals[LEAVE], 0, crossing->mode); + g_object_freeze_notify (G_OBJECT (motion)); if (motion->is_pointer != is_pointer) { @@ -118,6 +134,9 @@ update_pointer_focus (GtkEventController *controller, g_object_notify (G_OBJECT (motion), "contains-pointer"); } g_object_thaw_notify (G_OBJECT (motion)); + + if (enter) + g_signal_emit (controller, signals[ENTER], 0, x, y, crossing->mode); } static void @@ -133,13 +152,7 @@ gtk_event_controller_motion_handle_crossing (GtkEventController *controller, motion->current_crossing = crossing; - update_pointer_focus (controller, crossing); - - g_signal_emit (controller, signals[POINTER_CHANGE], 0, - crossing->direction, - x, - y, - crossing->mode); + update_pointer_focus (controller, crossing, x, y); motion->current_crossing = NULL; } @@ -216,34 +229,41 @@ gtk_event_controller_motion_class_init (GtkEventControllerMotionClass *klass) g_object_class_install_properties (object_class, NUM_PROPERTIES, props); /** - * GtkEventControllerMotion::pointer-change: + * GtkEventControllerMotion::enter: * @controller: the object which received the signal - * @direction: the direction of this crossing event * @x: coordinates of pointer location * @y: coordinates of pointer location * @mode: crossing mode * - * This signal is emitted whenever the pointer focus changes - * from or to a widget that is a descendant of the widget to - * which @controller is attached. - * - * Handlers for this signal can use - * gtk_event_controller_motion_get_pointer_origin() and - * gtk_event_controller_motion_get_pointer_target() to find - * the old and new pointer locations. + * Signals that the pointer has entered the widget. */ - signals[POINTER_CHANGE] = - g_signal_new (I_("pointer-change"), + signals[ENTER] = + g_signal_new (I_("enter"), GTK_TYPE_EVENT_CONTROLLER_MOTION, G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, - G_TYPE_NONE, 4, - GTK_TYPE_CROSSING_DIRECTION, + G_TYPE_NONE, 3, G_TYPE_DOUBLE, G_TYPE_DOUBLE, GDK_TYPE_CROSSING_MODE); + /** + * GtkEventControllerMotion::leave: + * @controller: the object which received the signal + * @mode: crossing mode + * + * Signals that the pointer has left the widget. + */ + signals[LEAVE] = + g_signal_new (I_("leave"), + GTK_TYPE_EVENT_CONTROLLER_MOTION, + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + NULL, + G_TYPE_NONE, 1, + GDK_TYPE_CROSSING_MODE); + /** * GtkEventControllerMotion::motion: * @controller: The object that received the signal @@ -290,7 +310,8 @@ gtk_event_controller_motion_new (void) * Returns the widget that contained the pointer before. * * This function can only be used in handlers for the - * #GtkEventControllerMotion::pointer-change signal. + * #GtkEventControllerMotion::enter or + * #GtkEventControllerMotion::leave signals. * * Returns: (transfer none): the previous pointer focus */ @@ -310,7 +331,8 @@ gtk_event_controller_motion_get_pointer_origin (GtkEventControllerMotion *contro * Returns the widget that will contain the pointer afterwards. * * This function can only be used in handlers for the - * #GtkEventControllerMotion::pointer-change signal. + * #GtkEventControllerMotion::enter or + * #GtkEventControllerMotion::leave signals. * * Returns: (transfer none): the next pointer focus */ diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c index 0efac0bac5..fdd62c29ba 100644 --- a/gtk/gtkiconview.c +++ b/gtk/gtkiconview.c @@ -166,10 +166,7 @@ static void gtk_icon_view_motion (GtkEventControl double x, double y, gpointer user_data); -static void gtk_icon_view_pointer (GtkEventController *controller, - GtkCrossingDirection direction, - double x, - double y, +static void gtk_icon_view_leave (GtkEventController *controller, GdkCrossingMode mode, gpointer user_data); static void gtk_icon_view_button_press (GtkGestureClick *gesture, @@ -967,10 +964,8 @@ gtk_icon_view_init (GtkIconView *icon_view) gtk_widget_add_controller (GTK_WIDGET (icon_view), GTK_EVENT_CONTROLLER (gesture)); controller = gtk_event_controller_motion_new (); - g_signal_connect (controller, "pointer-change", G_CALLBACK (gtk_icon_view_pointer), - icon_view); - g_signal_connect (controller, "motion", G_CALLBACK (gtk_icon_view_motion), - icon_view); + g_signal_connect (controller, "leave", G_CALLBACK (gtk_icon_view_leave), icon_view); + g_signal_connect (controller, "motion", G_CALLBACK (gtk_icon_view_motion), icon_view); gtk_widget_add_controller (GTK_WIDGET (icon_view), controller); controller = gtk_event_controller_key_new (); @@ -1883,26 +1878,20 @@ gtk_icon_view_motion (GtkEventController *controller, } static void -gtk_icon_view_pointer (GtkEventController *controller, - GtkCrossingDirection direction, - double x, - double y, - GdkCrossingMode mode, - gpointer user_data) +gtk_icon_view_leave(GtkEventController *controller, + GdkCrossingMode mode, + gpointer user_data) { GtkIconView *icon_view; GtkIconViewPrivate *priv; - if (direction == GTK_CROSSING_OUT) - { - icon_view = GTK_ICON_VIEW (user_data); - priv = icon_view->priv; + icon_view = GTK_ICON_VIEW (user_data); + priv = icon_view->priv; - if (priv->last_prelight) - { - gtk_icon_view_queue_draw_item (icon_view, priv->last_prelight); - priv->last_prelight = NULL; - } + if (priv->last_prelight) + { + gtk_icon_view_queue_draw_item (icon_view, priv->last_prelight); + priv->last_prelight = NULL; } } diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index 1c7d1ba130..306b01e2c7 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -448,10 +448,7 @@ static void gtk_label_motion (GtkEventControllerMotion *controller, double x, double y, gpointer data); -static void gtk_label_pointer (GtkEventControllerMotion *controller, - GtkCrossingDirection direction, - double x, - double y, +static void gtk_label_leave (GtkEventControllerMotion *controller, GdkCrossingMode mode, gpointer data); @@ -4859,24 +4856,18 @@ gtk_label_motion (GtkEventControllerMotion *controller, } static void -gtk_label_pointer (GtkEventControllerMotion *controller, - GtkCrossingDirection direction, - double x, - double y, - GdkCrossingMode mode, - gpointer data) +gtk_label_leave (GtkEventControllerMotion *controller, + GdkCrossingMode mode, + gpointer data) { GtkLabel *label = GTK_LABEL (data); GtkLabelPrivate *priv = gtk_label_get_instance_private (label); - if (direction == GTK_CROSSING_OUT) + if (priv->select_info) { - if (priv->select_info) - { - priv->select_info->active_link = NULL; - gtk_label_update_cursor (label); - gtk_widget_queue_draw (GTK_WIDGET (label)); - } + priv->select_info->active_link = NULL; + gtk_label_update_cursor (label); + gtk_widget_queue_draw (GTK_WIDGET (label)); } } @@ -5022,8 +5013,8 @@ gtk_label_ensure_select_info (GtkLabel *label) priv->select_info->motion_controller = gtk_event_controller_motion_new (); g_signal_connect (priv->select_info->motion_controller, "motion", G_CALLBACK (gtk_label_motion), label); - g_signal_connect (priv->select_info->motion_controller, "pointer-change", - G_CALLBACK (gtk_label_pointer), label); + g_signal_connect (priv->select_info->motion_controller, "leave", + G_CALLBACK (gtk_label_leave), label); gtk_widget_add_controller (GTK_WIDGET (label), priv->select_info->motion_controller); priv->select_info->provider = g_object_new (GTK_TYPE_LABEL_CONTENT, NULL); diff --git a/gtk/gtkmodelbutton.c b/gtk/gtkmodelbutton.c index 803006f95c..2f5d3aba9e 100644 --- a/gtk/gtkmodelbutton.c +++ b/gtk/gtkmodelbutton.c @@ -1312,23 +1312,23 @@ stop_open (GtkModelButton *button) } static void -pointer_change_cb (GtkEventController *controller, - GtkCrossingDirection direction, - double x, - double y, - GdkCrossingMode mode, - gpointer data) +pointer_cb (GObject *object, + GParamSpec *pspec, + gpointer data) { - GtkModelButton *button = data; - GtkWidget *target; - GtkWidget *popover; + gboolean contains; + + contains = gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (object)); - if (direction == GTK_CROSSING_IN) + if (contains) { - target = gtk_event_controller_get_widget (controller); + GtkWidget *target; + GtkWidget *popover; + + target = GTK_WIDGET (data); popover = gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU); - if (popover && gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))) + if (popover) { if (gtk_popover_menu_get_open_submenu (GTK_POPOVER_MENU (popover)) != NULL) start_open (GTK_MODEL_BUTTON (target)); @@ -1337,7 +1337,11 @@ pointer_change_cb (GtkEventController *controller, } } else - stop_open (button); + { + GtkModelButton *button = data; + + stop_open (button); + } } static void @@ -1383,7 +1387,7 @@ gtk_model_button_init (GtkModelButton *self) gtk_widget_add_css_class (GTK_WIDGET (self), "flat"); controller = gtk_event_controller_motion_new (); - g_signal_connect (controller, "pointer-change", G_CALLBACK (pointer_change_cb), self); + g_signal_connect (controller, "notify::contains-pointer", G_CALLBACK (pointer_cb), self); g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self); gtk_widget_add_controller (GTK_WIDGET (self), controller); diff --git a/gtk/gtkpopovermenu.c b/gtk/gtkpopovermenu.c index f9b494dfd3..2f73218d88 100644 --- a/gtk/gtkpopovermenu.c +++ b/gtk/gtkpopovermenu.c @@ -184,22 +184,15 @@ focus_out (GtkEventController *controller, } static void -pointer_cb (GtkEventController *controller, - GtkCrossingDirection direction, - double x, - double y, - GdkCrossingMode mode, - gpointer data) +leave_cb (GtkEventController *controller, + GdkCrossingMode mode, + gpointer data) { GtkWidget *target; - if (direction == GTK_CROSSING_OUT) - { - target = gtk_event_controller_get_widget (controller); + target = gtk_event_controller_get_widget (controller); - if (!gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))) - gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (target), NULL); - } + gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (target), NULL); } static void @@ -223,7 +216,7 @@ gtk_popover_menu_init (GtkPopoverMenu *popover) gtk_widget_add_controller (GTK_WIDGET (popover), controller); controller = gtk_event_controller_motion_new (); - g_signal_connect (controller, "pointer-change", G_CALLBACK (pointer_cb), popover); + g_signal_connect (controller, "leave", G_CALLBACK (leave_cb), popover); gtk_widget_add_controller (GTK_WIDGET (popover), controller); } diff --git a/gtk/gtkpopovermenubar.c b/gtk/gtkpopovermenubar.c index 2e9a1dec4b..411d4c0358 100644 --- a/gtk/gtkpopovermenubar.c +++ b/gtk/gtkpopovermenubar.c @@ -166,12 +166,11 @@ clicked_cb (GtkGesture *gesture, } static void -item_pointer_change_cb (GtkEventController *controller, - GtkCrossingDirection direction, - double x, - double y, - GdkCrossingMode mode, - gpointer data) +item_enter_cb (GtkEventController *controller, + double x, + double y, + GdkCrossingMode mode, + gpointer data) { GtkWidget *target; GtkPopoverMenuBar *bar; @@ -179,17 +178,13 @@ item_pointer_change_cb (GtkEventController *controller, target = gtk_event_controller_get_widget (controller); bar = GTK_POPOVER_MENU_BAR (gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU_BAR)); - if (direction == GTK_CROSSING_IN) - set_active_item (bar, GTK_POPOVER_MENU_BAR_ITEM (target), FALSE); + set_active_item (bar, GTK_POPOVER_MENU_BAR_ITEM (target), FALSE); } static void -bar_pointer_change_cb (GtkEventController *controller, - GtkCrossingDirection direction, - double x, - double y, - GdkCrossingMode mode, - gpointer data) +bar_leave_cb (GtkEventController *controller, + GdkCrossingMode mode, + gpointer data) { GtkWidget *target; GtkPopoverMenuBar *bar; @@ -197,12 +192,9 @@ bar_pointer_change_cb (GtkEventController *controller, target = gtk_event_controller_get_widget (controller); bar = GTK_POPOVER_MENU_BAR (gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU_BAR)); - if (direction == GTK_CROSSING_OUT) - { - if (bar->active_item && - !gtk_widget_get_mapped (GTK_WIDGET (bar->active_item->popover))) - set_active_item (bar, NULL, FALSE); - } + if (bar->active_item && + !gtk_widget_get_mapped (GTK_WIDGET (bar->active_item->popover))) + set_active_item (bar, NULL, FALSE); } static gboolean @@ -265,7 +257,7 @@ gtk_popover_menu_bar_item_init (GtkPopoverMenuBarItem *item) controller = gtk_event_controller_motion_new (); gtk_event_controller_set_propagation_limit (controller, GTK_LIMIT_NONE); - g_signal_connect (controller, "pointer-change", G_CALLBACK (item_pointer_change_cb), NULL); + g_signal_connect (controller, "enter", G_CALLBACK (item_enter_cb), NULL); gtk_widget_add_controller (GTK_WIDGET (item), controller); } @@ -617,7 +609,7 @@ gtk_popover_menu_bar_init (GtkPopoverMenuBar *bar) controller = gtk_event_controller_motion_new (); gtk_event_controller_set_propagation_limit (controller, GTK_LIMIT_NONE); - g_signal_connect (controller, "pointer-change", G_CALLBACK (bar_pointer_change_cb), NULL); + g_signal_connect (controller, "leave", G_CALLBACK (bar_leave_cb), NULL); gtk_widget_add_controller (GTK_WIDGET (bar), controller); } diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 71ca0a4fc4..30c4310ce2 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -445,22 +445,16 @@ add_tab_bindings (GtkBindingSet *binding_set, } static void -motion_controller_pointer (GtkEventController *controller, - GtkCrossingDirection direction, - double x, - double y, - GdkCrossingMode mode, - GtkScrolledWindow *scrolled_window) +motion_controller_leave (GtkEventController *controller, + GdkCrossingMode mode, + GtkScrolledWindow *scrolled_window) { GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window); - if (direction == GTK_CROSSING_OUT) + if (priv->use_indicators) { - if (priv->use_indicators) - { - indicator_set_over (&priv->hindicator, FALSE); - indicator_set_over (&priv->vindicator, FALSE); - } + indicator_set_over (&priv->hindicator, FALSE); + indicator_set_over (&priv->vindicator, FALSE); } } @@ -2024,8 +2018,8 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window) gtk_widget_add_controller (widget, controller); controller = gtk_event_controller_motion_new (); - g_signal_connect (controller, "pointer-change", - G_CALLBACK (motion_controller_pointer), scrolled_window); + g_signal_connect (controller, "leave", + G_CALLBACK (motion_controller_leave), scrolled_window); gtk_widget_add_controller (widget, controller); } diff --git a/gtk/gtktreepopover.c b/gtk/gtktreepopover.c index 019090e9aa..207f107699 100644 --- a/gtk/gtktreepopover.c +++ b/gtk/gtktreepopover.c @@ -619,21 +619,16 @@ item_activated_cb (GtkGesture *gesture, } static void -pointer_change_cb (GtkEventController *controller, - GtkCrossingDirection direction, - double x, - double y, - GdkCrossingMode mode, - GtkTreePopover *popover) +enter_cb (GtkEventController *controller, + double x, + double y, + GdkCrossingMode mode, + GtkTreePopover *popover) { GtkWidget *item; item = gtk_event_controller_get_widget (controller); - if (direction == GTK_CROSSING_IN) - { - if (gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))) - gtk_tree_popover_set_active_item (popover, item); - } + gtk_tree_popover_set_active_item (popover, item); } static GtkWidget * @@ -693,7 +688,7 @@ gtk_tree_popover_create_item (GtkTreePopover *popover, gtk_widget_add_controller (item, GTK_EVENT_CONTROLLER (controller)); controller = gtk_event_controller_motion_new (); - g_signal_connect (controller, "pointer-change", G_CALLBACK (pointer_change_cb), popover); + g_signal_connect (controller, "enter", G_CALLBACK (enter_cb), popover); gtk_widget_add_controller (item, controller); g_object_set_data (G_OBJECT (item), "is-header", GINT_TO_POINTER (header_item)); diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index b203ed5770..1904160a49 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -970,12 +970,14 @@ static void gtk_tree_view_drag_gesture_end (GtkGestureDrag *ges gdouble offset_x, gdouble offset_y, GtkTreeView *tree_view); -static void gtk_tree_view_motion_controller_pointer (GtkEventControllerMotion *controller, - GtkCrossingDirection direction, +static void gtk_tree_view_motion_controller_enter (GtkEventControllerMotion *controller, double x, double y, GdkCrossingMode mode, GtkTreeView *tree_view); +static void gtk_tree_view_motion_controller_leave (GtkEventControllerMotion *controller, + GdkCrossingMode mode, + GtkTreeView *tree_view); static void gtk_tree_view_motion_controller_motion (GtkEventControllerMotion *controller, double x, double y, @@ -1821,8 +1823,10 @@ gtk_tree_view_init (GtkTreeView *tree_view) gtk_widget_add_controller (GTK_WIDGET (tree_view), GTK_EVENT_CONTROLLER (tree_view->column_drag_gesture)); controller = gtk_event_controller_motion_new (); - g_signal_connect (controller, "pointer-change", - G_CALLBACK (gtk_tree_view_motion_controller_pointer), tree_view); + g_signal_connect (controller, "enter", + G_CALLBACK (gtk_tree_view_motion_controller_enter), tree_view); + g_signal_connect (controller, "leave", + G_CALLBACK (gtk_tree_view_motion_controller_leave), tree_view); g_signal_connect (controller, "motion", G_CALLBACK (gtk_tree_view_motion_controller_motion), tree_view); gtk_widget_add_controller (GTK_WIDGET (tree_view), controller); @@ -5497,46 +5501,45 @@ gtk_tree_view_key_controller_key_released (GtkEventControllerKey *key, } static void -gtk_tree_view_motion_controller_pointer (GtkEventControllerMotion *controller, - GtkCrossingDirection direction, - double x, - double y, - GdkCrossingMode mode, - GtkTreeView *tree_view) +gtk_tree_view_motion_controller_enter (GtkEventControllerMotion *controller, + double x, + double y, + GdkCrossingMode mode, + GtkTreeView *tree_view) { GtkTreeRBTree *tree; GtkTreeRBNode *node; gint new_y; - if (direction == GTK_CROSSING_IN) - { - if (tree_view->tree == NULL) - return; + if (tree_view->tree == NULL) + return; - /* find the node internally */ - new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, y); - if (new_y < 0) - new_y = 0; - gtk_tree_rbtree_find_offset (tree_view->tree, new_y, &tree, &node); + /* find the node internally */ + new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, y); + if (new_y < 0) + new_y = 0; + gtk_tree_rbtree_find_offset (tree_view->tree, new_y, &tree, &node); - tree_view->event_last_x = x; - tree_view->event_last_y = y; + tree_view->event_last_x = x; + tree_view->event_last_y = y; - if ((tree_view->button_pressed_node == NULL) || - (tree_view->button_pressed_node == node)) - prelight_or_select (tree_view, tree, node, x, y); - } - else - { - if (tree_view->prelight_node) - gtk_widget_queue_draw (GTK_WIDGET (tree_view)); + if ((tree_view->button_pressed_node == NULL) || + (tree_view->button_pressed_node == node)) + prelight_or_select (tree_view, tree, node, x, y); +} - tree_view->event_last_x = -10000; - tree_view->event_last_y = -10000; +static void +gtk_tree_view_motion_controller_leave (GtkEventControllerMotion *controller, + GdkCrossingMode mode, + GtkTreeView *tree_view) +{ + if (tree_view->prelight_node) + gtk_widget_queue_draw (GTK_WIDGET (tree_view)); - if (!gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))) - prelight_or_select (tree_view, NULL, NULL, -1000, -1000); /* not possibly over an arrow */ - } + tree_view->event_last_x = -10000; + tree_view->event_last_y = -10000; + + prelight_or_select (tree_view, NULL, NULL, -1000, -1000); /* not possibly over an arrow */ } static void diff --git a/testsuite/gtk/focus.c b/testsuite/gtk/focus.c index 854236d57d..380ddb2419 100644 --- a/testsuite/gtk/focus.c +++ b/testsuite/gtk/focus.c @@ -15,7 +15,7 @@ widget_name (GtkWidget *widget) static void focus_in (GtkEventControllerFocus *key, - GString *s) + GString *s) { GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (key)); @@ -27,7 +27,7 @@ focus_in (GtkEventControllerFocus *key, static void focus_out (GtkEventControllerFocus *key, - GString *s) + GString *s) { GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (key)); @@ -48,6 +48,15 @@ add_controller (GtkWidget *widget, GString *s) gtk_widget_add_controller (widget, controller); } +static void +assert_result (const char *s, const char *expected) +{ + if (strcmp (s, expected) != 0 && g_test_verbose ()) + g_print ("Expected:\n%s", expected); + + g_assert_cmpstr (s, ==, expected); +} + static void test_window_focus (void) { @@ -117,10 +126,8 @@ test_window_focus (void) if (g_test_verbose ()) g_print ("-> box\n%s\n", s->str); - g_assert_cmpstr (s->str, ==, -"window: focus-in is-focus: 0 contains-focus: 1\n" -"box: focus-in is-focus: 1 contains-focus: 1\n" - ); + assert_result (s->str, "window: focus-in is-focus: 0 contains-focus: 1\n" +"box: focus-in is-focus: 1 contains-focus: 1\n"); g_string_truncate (s, 0); gtk_widget_grab_focus (entry1); @@ -128,14 +135,9 @@ test_window_focus (void) if (g_test_verbose ()) g_print ("box -> entry1\n%s\n", s->str); - g_assert_cmpstr (s->str, ==, -"box: focus-out is-focus: 0 contains-focus: 0\n" -"window: focus-out is-focus: 0 contains-focus: 0\n" -"window: focus-in is-focus: 0 contains-focus: 1\n" -"box: focus-in is-focus: 0 contains-focus: 1\n" + assert_result (s->str, "box1: focus-in is-focus: 0 contains-focus: 1\n" -"entry1: focus-in is-focus: 1 contains-focus: 1\n" - ); +"entry1: focus-in is-focus: 1 contains-focus: 1\n"); g_string_truncate (s, 0); @@ -146,16 +148,11 @@ test_window_focus (void) if (g_test_verbose ()) g_print ("entry1 -> entry2\n%s\n", s->str); - g_assert_cmpstr (s->str, ==, -"entry1: focus-out is-focus: 0 contains-focus: 0\n" -"box1: focus-out is-focus: 0 contains-focus: 0\n" -"box: focus-out is-focus: 0 contains-focus: 0\n" -"window: focus-out is-focus: 0 contains-focus: 0\n" -"window: focus-in is-focus: 0 contains-focus: 1\n" -"box: focus-in is-focus: 0 contains-focus: 1\n" + assert_result (s->str, +"entry1: focus-out is-focus: 1 contains-focus: 1\n" +"box1: focus-out is-focus: 0 contains-focus: 1\n" "box2: focus-in is-focus: 0 contains-focus: 1\n" -"entry2: focus-in is-focus: 1 contains-focus: 1\n" - ); +"entry2: focus-in is-focus: 1 contains-focus: 1\n"); g_string_truncate (s, 0); @@ -166,14 +163,10 @@ test_window_focus (void) if (g_test_verbose ()) g_print ("entry2 -> box\n%s", s->str); - g_assert_cmpstr (s->str, ==, -"entry2: focus-out is-focus: 0 contains-focus: 0\n" -"box2: focus-out is-focus: 0 contains-focus: 0\n" -"box: focus-out is-focus: 0 contains-focus: 0\n" -"window: focus-out is-focus: 0 contains-focus: 0\n" -"window: focus-in is-focus: 0 contains-focus: 1\n" -"box: focus-in is-focus: 1 contains-focus: 1\n" - ); + assert_result (s->str, +"entry2: focus-out is-focus: 1 contains-focus: 1\n" +"box2: focus-out is-focus: 0 contains-focus: 1\n" + ); g_string_truncate (s, 0); -- 2.30.2